﻿using System;
using System.Collections.Generic;
using System.Linq;
using FBEntities.FBConnections;
using FBEntities.FBConnections.User;
using FBEntities.FBObjects.User;
using Newtonsoft.Json.Linq;
using XDAFacebook;
using XFControls.Utils;

namespace FBEntities.FBObjects
{
    public class FBPost : IFBUpdatable
    {
        public List<FBAction> actions;
        public string attribution;
        public string caption;
        public FBComments comments;
        protected FBCommentsConnection commentsConnection;
        public DateTime created_time;
        public string description;
        public FBFrom from;
        public string icon;
        public string id;
        public FBLikesConnection likes;
        public string link;
        public string message;
        public string name;
        public string picture;
        public string source;
        public FBTo to;
        public string type;
        public DateTime updated_time;

        public FBPost()
        {
            actions = new List<FBAction>();
        }

        public FBCommentsConnection Comments
        {
            get { return commentsConnection ?? (commentsConnection = new FBCommentsConnection()); }
            protected set { commentsConnection = value; }
        }

        public FBLikesConnection PeopleWhoLiked
        {
            get { return likes ?? (likes = new FBLikesConnection()); }
            set { likes = value; }
        }

        #region IFBUpdatable Members

        public void Parse(JObject text)
        {
            FBParseUtilities.Parse(text, this);
        }

        public event UpdateEventHandler Updated;

        #endregion

        public static FBPost PostOnWall(FBPost post)
        {
            string authKeyCode = FBParseUtilities.authKeySplit;
            var args = new Dictionary<string, string>();
            args.Add("access_token", authKeyCode);
            args.Add("message", post.message);

            string id = post.to.data[0].id;

            string json = WebDownloader.MakeRequest(new Uri(string.Format("https://graph." + Settings.Domain + ".com/{0}/feed", id)), HttpVerb.POST,
                                                    args);

            var ret = new FBPost();
            JObject obj = JObject.Parse(json);
            ret.id = obj["id"].ToString().Trim('\"');

            ret.Parse();
            return ret;
        }

        public void Parse()
        {
            if (string.IsNullOrEmpty(id))
                return;

            string url = "https://graph." + Settings.Domain + ".com/" + id + "?" + FBParseUtilities.authKey;
            var wrapper = new WebDownloaderWrapper(url);
            string json = wrapper.Download();
            JObject o = JObject.Parse(json);
            Parse(o);
        }

        public void ParseGetUser()
        {
            ParseGetUser(!id.Contains("_"));
        }

        private void ParseGetUser(bool loop)
        {
            if (string.IsNullOrEmpty(id))
                return;

            string url = "https://graph." + Settings.Domain + ".com/" + id + "?" + FBParseUtilities.authKey;
            var wrapper = new WebDownloaderWrapper(url);
            string json = wrapper.Download();
            JObject o = JObject.Parse(json);
            Parse(o);

            if (!loop) return;

            id = from.id + "_" + id;
            ParseGetUser(false);
        }

        public WebDownloaderWrapper Like()
        {
            var ret = FBParseUtilities.Like(id);
            return ret;
        }

        public WebDownloaderWrapper AddComment(string comment)
        {
            return FBParseUtilities.PostText(id, "comments", comment);
        }

        public WebDownloaderWrapper Delete()
        {
            string authKeyCode = FBParseUtilities.authKeySplit;
            var args = new Dictionary<string, string>();
            args.Add("access_token", authKeyCode);

            return new WebDownloaderWrapper(string.Format("https://graph." + Settings.Domain + ".com/{0}", id)) { PostData = args };
        }
    }

    public class FBProxyPerson : IFBObject
    {
        public FBPicture Picture;
        public string category;
        public string id;
        public string name;
        public string status;

        public FBProxyPerson() { }

        public FBProxyPerson(string personId)
        {
            id = personId;
            Picture = new FBPicture(id);

            var friends = new FBFriends();
            friends.ParseCached();

            var person = friends.data.FirstOrDefault(f => f.id == personId);

            if (person == null)
                return;

            name = person.name;
            category = person.category;
        }

        #region IFBObject Members

        public void Parse(JObject text)
        {
            FBParseUtilities.Parse(text, this);

            Picture = new FBPicture(id);
        }

        #endregion

        public FBPerson ToPerson()
        {
            var ret = new FBPerson();
            ret.id = id;
            ret.name = name;

            return ret;
        }
    }

    public class FBFrom : FBProxyPerson { }

    public class FBTo : IFBObject
    {
        public List<FBProxyPerson> data;

        public FBTo()
        {
            data = new List<FBProxyPerson>();
        }

        #region IFBObject Members

        public void Parse(JObject text)
        {
            FBParseUtilities.Parse(text, this);
        }

        #endregion
    }

    public class FBSearch : IFBObject
    {
        public List<FBPost> data;
        public FBPaging paging;

        #region IFBObject Members

        public FBSearch()
        {
            data = new List<FBPost>();
        }

        public void Parse(JObject o)
        {
            FBParseUtilities.Parse(o, this);
        }

        #endregion
    }

}